#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
#include "c-utils/utils.h"

int __test_file_write_read()
{
    const char *test_file_name = "file_test";
    const char *ctx1 = "hello!";
    const char *ctx2 = "world!";
    int ctx1_len = strlen(ctx1);
    int ctx2_len = strlen(ctx2);
    if (utils_file_write(test_file_name, 0, ctx1, ctx1_len) != ctx1_len)
    {
        printf("create file failed\n");
        return -1;
    }

    if (euidaccess(test_file_name, F_OK | R_OK | W_OK | X_OK) != 0)
    {
        printf("access permssion failed\n");
        return -1;
    }

    if (utils_file_write(test_file_name, ctx1_len, ctx2, ctx2_len) != ctx2_len)
    {
        printf("write failed\n");
        return -1;
    }

    char *out = calloc(ctx1_len + ctx2_len, sizeof(char));
    int ret = -1;
    int len = utils_file_read(test_file_name, 0, out, ctx1_len + ctx2_len);
    if (len != ctx1_len + ctx2_len)
    {
        printf("read failed: len: %d ,ctx1 + ctx2: %d\n", len, ctx1_len + ctx2_len);
        goto RETURN;
    }

    if (strncmp(out, ctx1, ctx1_len))
    {
        printf("cmp ctx1 failed\n");
        goto RETURN;
    }

    if (strncmp(out + ctx1_len, ctx2, ctx2_len))
    {
        printf("cmp ctx2 failed\n");
        goto RETURN;
    }
    ret = 0;

RETURN:
    free(out);
    remove(test_file_name);
    return ret;
}

int __test_file_remove_all(const char *path)
{
    char cmd[PATH_MAX] = {0};
    snprintf(cmd, sizeof(cmd), "mkdir -p %s/a/a %s/b/b %s/c", path, path, path);
    utils_shell(cmd, NULL, 0);
    bzero(cmd, sizeof(cmd));
    snprintf(cmd, sizeof(cmd), "touch %s/a/a/aaa ; touch %s/b/bbb", path, path);
    utils_shell(cmd, NULL, 0);
    if (utils_file_remove_all(path))
        return -1;
    if (euidaccess(path, F_OK) == 0)
    {
        return -1;
    }
    int ret = 0;
    return ret;
}

void __test_file_search(const char *path, void *priv_data)
{
    printf("path: %s, priv: %p, %d\n", path, priv_data, *(int *)priv_data);
}

int test_file(int argc, char *argv[])
{
    if (__test_file_write_read())
        return -1;

    if (__test_file_remove_all("/tmp/c-utils"))
        return -1;
    if (argc == 4)
    {
        int p = 1;
        utils_file_search(argv[1], argv[2], atoi(argv[3]), true, __test_file_search, &p);
    }
    return 0;
}